package toolkits;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

public class NIOTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		NIOTest test = new NIOTest();
		//test.readBinarySequence(new File("C:/c7ps/pssettings/sequence"));
		System.out.print(test.next());
		

	}

	public void out(Object obj) {
		System.out.println(obj.toString());
	}

	/**
	 * @return
	 */
	public long next() {

		Charset charset = Charset.forName("ISO-8859-15");
		CharsetDecoder decoder = charset.newDecoder();
		CharsetEncoder encoder = charset.newEncoder();
		
		long seqValue = 942000000004L;
		try {
			// Get a file channel for the file
			final File binaryFile = new File("C:/c7ps/pssettings/sequence");
			final File asciiFile = new File("C:/sequence.ascii");
			
			boolean needMigrate=binaryFile.exists() && !asciiFile.exists();
			// Use the file channel to create a lock on the file.
			// This method blocks until it can retrieve the lock.
			FileLock lock = null;
			synchronized (this) {
				
				if(needMigrate){
					seqValue=readBinarySequence(binaryFile);
				}
				
				FileChannel channel = new RandomAccessFile(asciiFile, "rw").getChannel();
				try {
					lock = channel.lock();
				} catch (OverlappingFileLockException overlappingFileLockException) {
					overlappingFileLockException.printStackTrace();
				}
				out("c1 size:" + channel.size());
				
				ByteBuffer byteBuf=ByteBuffer.allocate(String.valueOf(Long.MAX_VALUE).length());
				channel.read(byteBuf);
				byteBuf.rewind();
				
				String long_str=decoder.decode(byteBuf).toString().trim();
				if(long_str!=null && !"".equals(long_str) && !needMigrate){
					seqValue = Long.parseLong(long_str);
				}
	
				out(long_str.length()+">"+long_str);
				
				
				CharBuffer charBuf=CharBuffer.wrap(String.valueOf(seqValue+1));
				channel.position(0);
				channel.write(encoder.encode(charBuf));
				
				lock.release();
				channel.close();
			}
			// Close the file

		} catch (Exception e) {
			e.printStackTrace();
		}
		return seqValue;
	}
	
	public long readBinarySequence(final File file) {


		long seqValue = 942000000004L;
		try {
			// Get a file channel for the file
			// Use the file channel to create a lock on the file.
			// This method blocks until it can retrieve the lock.
			FileLock lock = null;

				FileChannel channel = new RandomAccessFile(file, "rw")
						.getChannel();
				try {
					lock = channel.lock();
				} catch (OverlappingFileLockException overlappingFileLockException) {
					overlappingFileLockException.printStackTrace();
				}

				
				ByteBuffer wrBuf = channel.map(FileChannel.MapMode.READ_WRITE,0, 8);
				try {
					seqValue = wrBuf.getLong();
					out("sequnce in file:"+seqValue);
				} catch (BufferUnderflowException bufferUnderflowException) {
					bufferUnderflowException.printStackTrace();
				}
				/*
				wrBuf.rewind();
				wrBuf.putLong(seqValue + 1);
				channel.write(wrBuf);*/
				// Release the lock
				lock.release();
				channel.close();
			// Close the file

		} catch (Exception e) {
			e.printStackTrace();
		}
		return seqValue;
	}

}
